package ${packageName};
                    
import mobile.game.core.CallPoint;
import mobile.game.core.Port;
<#if hasDefault>
import mobile.game.core.config.JowDistr;
import mobile.game.core.support.log.LogCore;
</#if>
import mobile.game.core.support.Param;
import mobile.game.core.support.Utils;
import mobile.game.core.support.function.*;
import mobile.game.core.gen.proxy.RPCProxyBase;
<#if importPackages??>
<#list importPackages as package>
import ${package};
</#list>
</#if>
import mobile.game.core.gen.JowGenFile;

${mainAnnotation}
@JowGenFile
public class RPCProxy {
	<#list methodsList as proxy>
	public static final class ${proxy.className}Proxy extends RPCProxyBase {
		public final class EnumCall{
			<#assign i = 0>
			<#list proxy.methods as method>
			<#assign i = i + 1>
			public static final int ${method.enumCall} = ${i};
			</#list>
		}
		<#if proxy.hasDefault>
		private static final String SERV_ID = "${proxy.servId}";
		</#if>
		
		private CallPoint remote;
		private Port localPort;
		private String callerInfo;
		
		/**
		 * 私有构造函数
		 * 防止实例被私自创建 必须通过newInstance函数
		 */
		private ${proxy.className}Proxy() {}
	
		<#if proxy.hasDefault>
		/**
		 * 获取实例
		 * 大多数情况下可用此函数获取
		 * @param localPort
		 * @return
		 */
		public static ${proxy.className}Proxy newInstance() {
			String portId = JowDistr.getPortId(SERV_ID);
			if(portId == null) {
				LogCore.remote.error("通过servId未能找到上级Port: servId={}", SERV_ID);
				return null;
			}
		
			String nodeId = JowDistr.getNodeId(portId);
			if(nodeId == null) {
				LogCore.remote.error("通过portId未能找到上级Node: portId={}", portId);
				return null;
			}
		
			return createInstance(nodeId, portId, SERV_ID);
		}
		</#if>
		
		<#if !proxy.hasDefault>
		/**
		 * 获取实例
		 * @return
		 */
		public static ${proxy.className}Proxy newInstance(CallPoint targetPoint) {
			return createInstance(targetPoint.nodeId, targetPoint.portId, targetPoint.servId);
		}
		
		/**
		 * 获取实例
		 * @return
		 */
		public static ${proxy.className}Proxy newInstance(String node, String port, Object id) {
			return createInstance(node, port, id);
		}
		</#if>
		
		/**
		 * 创建实例
		 * @param localPort
		 * @param node
		 * @param port
		 * @param id
		 * @return
		 */
		private static ${proxy.className}Proxy createInstance(String node, String port, Object id) {
			${proxy.className}Proxy inst = new ${proxy.className}Proxy();
			inst.localPort = Port.getCurrent();
			inst.remote = new CallPoint(node, port, id);
			
			return inst;
		}
		
		/**
		 * 监听返回值
		 * @param obj
		 * @param methodName
		 * @param context
		 */
		public void listenResult(JowFunction2<Param, Param> method, Object...context) {
			listenResult(method, new Param(context));
		}
		
		/**
		 * 监听返回值
		 * @param obj
		 * @param methodName
		 * @param context
		 */
		public void listenResult(JowFunction2<Param, Param> method, Param context) {
			context.put("_callerInfo", callerInfo);
			localPort.listenResult(method, context);
		}
		
		
		public void listenResult(JowFunction3<Boolean, Param, Param> method, Object...context) {
			listenResult(method, new Param(context));
		}
		
		public void listenResult(JowFunction3<Boolean, Param, Param> method, Param context) {
			context.put("_callerInfo", callerInfo);
			localPort.listenResult(method, context);
		}
		
		
		/**
		 * 等待返回值
		 */
		public Param waitForResult() {
			return localPort.waitForResult();
		}
		<#list proxy.methods as method>
		
		public void ${method.name}(${method.params}) {
			callerInfo = Utils.getCallerInfo();
			localPort.call(remote, EnumCall.${method.enumCall}, new Object[]{ ${method.paramsCall} });
		}
		</#list>
	}
	
	</#list>
}